package repository

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"

	"github.com/google/uuid"
	"gorm.io/gorm"
	"techoiceness.com/aiagent/llm-gateway/internal/entity"
)

// LLMProviderRepositoryImpl LLMProvider 仓库实现
type LLMProviderRepositoryImpl struct {
	db *gorm.DB
}

// NewLLMProviderRepository 创建 LLMProvider 仓库
func NewLLMProviderRepository(db *gorm.DB) LLMProviderRepository {
	return &LLMProviderRepositoryImpl{
		db: db,
	}
}

// CreateProvider 创建提供商
func (r *LLMProviderRepositoryImpl) CreateProvider(ctx context.Context, provider *entity.LLMProvider) error {
	// 如果 provider 的 IsDefault 为 true，需要将其他默认的 provider 取消默认，需使用事务处理
	if provider.IsDefault {
		err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
			// 先将所有默认的 provider 取消默认
			if err := tx.Model(&entity.LLMProvider{}).
				Where("is_default = ?", true).
				Update("is_default", false).Error; err != nil {
				return fmt.Errorf("取消其他默认 provider 失败: %w", err)
			}
			// 创建当前 provider
			if err := tx.Create(provider).Error; err != nil {
				return fmt.Errorf("创建 provider 失败: %w", err)
			}
			return nil
		})
		return err
	}

	if err := r.db.WithContext(ctx).Create(provider).Error; err != nil {
		return fmt.Errorf("创建提供商失败: %w", err)
	}
	return nil
}

// GetProviderByID 根据ID获取提供商
func (r *LLMProviderRepositoryImpl) GetProviderByID(ctx context.Context, id uuid.UUID) (*entity.LLMProvider, error) {
	var provider entity.LLMProvider
	if err := r.db.WithContext(ctx).First(&provider, "id = ?", id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("找不到提供商: %s", id)
		}
		return nil, fmt.Errorf("获取提供商失败: %w", err)
	}
	return &provider, nil
}

// UpdateProvider 更新提供商
func (r *LLMProviderRepositoryImpl) UpdateProvider(ctx context.Context, provider *entity.LLMProvider) error {
	if err := r.db.WithContext(ctx).Save(provider).Error; err != nil {
		return fmt.Errorf("更新提供商失败: %w", err)
	}
	return nil
}

// DeleteProvider 删除提供商
func (r *LLMProviderRepositoryImpl) DeleteProvider(ctx context.Context, id uuid.UUID) error {
	// 检查是否为默认提供商
	var provider entity.LLMProvider
	if err := r.db.WithContext(ctx).First(&provider, "id = ?", id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return fmt.Errorf("找不到提供商: %s", id)
		}
		return fmt.Errorf("获取提供商失败: %w", err)
	}

	if provider.IsDefault {
		return fmt.Errorf("不能删除默认提供商")
	}

	if err := r.db.WithContext(ctx).Delete(&entity.LLMProvider{}, "id = ?", id).Error; err != nil {
		return fmt.Errorf("删除提供商失败: %w", err)
	}
	return nil
}

// QueryProviders 根据条件和分页参数查询提供商
func (r *LLMProviderRepositoryImpl) QueryProviders(ctx context.Context, opts LLMProviderQueryOptions) (LLMProviderQueryResult, error) {
	var providers []entity.LLMProvider
	var total int64

	tx := r.db.WithContext(ctx).Model(&entity.LLMProvider{})

	if opts.ProviderType != "" {
		tx = tx.Where("provider_type = ?", opts.ProviderType)
	}

	if opts.IsEnabled != nil {
		tx = tx.Where("is_enabled = ?", *opts.IsEnabled)
	}

	if opts.IsDefault != nil {
		tx = tx.Where("is_default = ?", *opts.IsDefault)
	}

	if err := tx.Count(&total).Error; err != nil {
		return LLMProviderQueryResult{}, fmt.Errorf("获取提供商数量失败: %w", err)
	}

	offset := (opts.Page - 1) * opts.PageSize

	if err := tx.Order("created_at DESC").
		Limit(opts.PageSize).
		Offset(offset).
		Find(&providers).Error; err != nil {
		return LLMProviderQueryResult{}, fmt.Errorf("获取提供商失败: %w", err)
	}

	return LLMProviderQueryResult{
		Providers: providers,
		Total:     total,
		Page:      opts.Page,
		PageSize:  opts.PageSize,
	}, nil
}

// GetEnabledProviders 获取启用的提供商
func (r *LLMProviderRepositoryImpl) GetEnabledProviders(ctx context.Context) ([]entity.LLMProvider, error) {
	var providers []entity.LLMProvider
	if err := r.db.WithContext(ctx).Where("is_enabled = ?", true).Order("created_at DESC").Find(&providers).Error; err != nil {
		return nil, fmt.Errorf("获取启用提供商失败: %w", err)
	}
	return providers, nil
}

// GetDefaultProvider 获取默认的提供商
func (r *LLMProviderRepositoryImpl) GetDefaultProvider(ctx context.Context) (*entity.LLMProvider, error) {
	var provider entity.LLMProvider
	if err := r.db.WithContext(ctx).Where("is_default = ?", true).First(&provider).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("找不到默认的提供商")
		}
		return nil, fmt.Errorf("获取默认的提供商失败: %w", err)
	}
	return &provider, nil
}

// GetAvailableProvider 获取一个可用的 Provider，优先返回默认的，如果没有默认则返回第一个启用的
func (r *LLMProviderRepositoryImpl) GetAvailableProvider(ctx context.Context) (*entity.LLMProvider, error) {
	// 优先获取默认的提供商
	if provider, err := r.GetDefaultProvider(ctx); err == nil {
		return provider, nil
	}

	// 如果没有默认的提供商，获取最新的启用的且 models 字段不为空的提供商
	var provider entity.LLMProvider
	if err := r.db.WithContext(ctx).
		Where("is_enabled = ?", true).
		Where("models IS NOT NULL").
		Where("jsonb_array_length(models) > 0").
		Order("updated_at DESC").
		First(&provider).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("找不到可用的提供商")
		}
		return nil, fmt.Errorf("获取当前使用提供商失败: %w", err)
	}
	return &provider, nil
}

// SetProviderDefault 设置默认提供商
func (r *LLMProviderRepositoryImpl) SetProviderDefault(ctx context.Context, id uuid.UUID, isDefault bool) error {
	// 使用事务确保数据一致性
	return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		// 检查提供商是否存在
		var provider entity.LLMProvider
		if err := tx.First(&provider, "id = ?", id).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return fmt.Errorf("找不到提供商: %s", id)
			}
			return fmt.Errorf("获取提供商失败: %w", err)
		}

		// 检查提供商是否有可用模型
		if provider.Models == nil {
			return fmt.Errorf("提供商 %s 没有模型", id)
		} else {
			var models []entity.ModelInfo
			if err := json.Unmarshal(provider.Models, &models); err != nil {
				return fmt.Errorf("解析提供商 %s 的模型失败: %w", id, err)
			}
			if len(models) == 0 {
				return fmt.Errorf("提供商 %s 模型数量为0", id)
			}
		}

		// 先将所有默认提供商的 is_default 字段设置为 false
		if err := tx.Model(&entity.LLMProvider{}).
			Where("is_default = ?", true).
			Update("is_default", false).Error; err != nil {
			return fmt.Errorf("取消默认提供商失败: %w", err)
		}

		// 设置指定提供商的默认状态
		if err := tx.Model(&entity.LLMProvider{}).Where("id = ?", id).Updates(map[string]interface{}{
			"is_default": isDefault,
			"is_enabled": true, // 默认提供商必须是启用的
		}).Error; err != nil {
			return fmt.Errorf("设置默认提供商失败: %w", err)
		}

		return nil
	})
}

// SetProviderEnabled 切换提供商活跃状态
func (r *LLMProviderRepositoryImpl) SetProviderEnabled(ctx context.Context, id uuid.UUID, isEnabled bool) error {
	// 如果要禁用提供商，先检查是否为默认提供商
	if !isEnabled {
		var provider entity.LLMProvider
		if err := r.db.WithContext(ctx).First(&provider, "id = ?", id).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return fmt.Errorf("找不到提供商: %s", id)
			}
			return fmt.Errorf("获取提供商失败: %w", err)
		}

		if provider.IsDefault {
			return fmt.Errorf("不能禁用默认提供商")
		}
	}

	if err := r.db.WithContext(ctx).Model(&entity.LLMProvider{}).Where("id = ?", id).Update("is_enabled", isEnabled).Error; err != nil {
		return fmt.Errorf("切换提供商活跃状态失败: %w", err)
	}
	return nil
}

// GetProviderCount 获取提供商数量
func (r *LLMProviderRepositoryImpl) GetProviderCount(ctx context.Context) (int64, error) {
	var count int64
	if err := r.db.WithContext(ctx).Model(&entity.LLMProvider{}).Count(&count).Error; err != nil {
		return 0, fmt.Errorf("获取提供商数量失败: %w", err)
	}
	return count, nil
}

// GetProviderCountByType 获取指定类型的提供商数量
func (r *LLMProviderRepositoryImpl) GetProviderCountByType(ctx context.Context, providerType string) (int64, error) {
	var count int64
	if err := r.db.WithContext(ctx).Model(&entity.LLMProvider{}).Where("provider_type = ?", providerType).Count(&count).Error; err != nil {
		return 0, fmt.Errorf("获取指定类型的提供商数量失败: %w", err)
	}
	return count, nil
}
